package com.atjg.autocat.utils

import android.app.Activity
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.hardware.usb.UsbManager
import android.util.Base64
import android.util.Log
import com.zhy.baselibrary.utils.Klog
import com.zkteco.android.biometric.core.device.ParameterHelper
import com.zkteco.android.biometric.core.device.TransportType
import com.zkteco.android.biometric.core.utils.LogHelper
import com.zkteco.android.biometric.core.utils.ToolUtils
import com.zkteco.android.biometric.module.fingerprintreader.FingerprintCaptureListener
import com.zkteco.android.biometric.module.fingerprintreader.FingerprintSensor
import com.zkteco.android.biometric.module.fingerprintreader.FingprintFactory
import com.zkteco.android.biometric.module.fingerprintreader.ZKFingerService
import com.zkteco.android.biometric.module.fingerprintreader.exception.FingerprintException

class FingerUtils {
    private val regtemparray = Array(3) { ByteArray(2048) }
    private var isRegister = false
    private var bstart = false
    private var enrollidx = 0
    private val VID: Int = 6997
    private val PID: Int = 288
    private val lastRegTemp = ByteArray(2048)
    private var fingerprintSensor: FingerprintSensor? = null


    companion object {
        private var fingerUtils: FingerUtils? = null
        fun initFinger(): FingerUtils {
            if (fingerUtils == null) {
                fingerUtils = FingerUtils()
            }
            return fingerUtils!!
        }
    }

    fun startFingerprintSensor(mContext: Context): FingerUtils {
        LogHelper.setLevel(Log.ASSERT)
        LogHelper.setNDKLogLevel(Log.ASSERT)
        // Start fingerprint sensor
        val fingerprintParams: MutableMap<String, Any> = HashMap()

        //set vid
        fingerprintParams[ParameterHelper.PARAM_KEY_VID] = VID

        //set pid
        fingerprintParams[ParameterHelper.PARAM_KEY_PID] = PID
        fingerprintSensor =
            FingprintFactory.createFingerprintSensor(mContext, TransportType.USB, fingerprintParams)
        return fingerUtils!!
    }

    fun initUSBPermission(mContext: Context): FingerUtils {
        val usbManager = mContext.getSystemService(Context.USB_SERVICE) as UsbManager
        for (device in usbManager.deviceList.values) {
            if (device.vendorId == VID && device.productId == PID) {
                val intent = Intent("com.zkteco.silkiddemo.USB_PERMISSION")
                val pendingIntent =
                    PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE)
                usbManager.requestPermission(device, pendingIntent)
            }
        }
        return fingerUtils!!
    }

    //开始识别指纹
    @Throws(FingerprintException::class)
    fun onBnBegin(mActivity: Activity, onFingerListener: OnFingerListener): FingerUtils {
        try {
            if (bstart) return fingerUtils!!
            fingerprintSensor?.open(0)
            onFingerListener.connectComplete()
            val listener: FingerprintCaptureListener = object : FingerprintCaptureListener {
                override fun captureOK(fpImage: ByteArray) {
                    val width = if ((fingerprintSensor?.imageWidth ?: 0) <= 0) {
                        100
                    } else {
                        fingerprintSensor?.imageWidth ?: 100
                    } ?: 100
                    val height = if ((fingerprintSensor?.imageHeight ?: 0) <= 0) {
                        100
                    } else {
                        fingerprintSensor?.imageHeight ?: 100
                    } ?: 100
                    val bitmapFp =
                        ToolUtils.renderCroppedGreyScaleBitmap(fpImage, width, height)
                    onFingerListener.captureOK(bitmapFp)
                }

                override fun captureError(e: FingerprintException) {
                    onFingerListener.captureFail(e,"captureError")
                }

                override fun extractError(err: Int) {
                    onFingerListener.extractError(err)
                }

                override fun extractOK(fpTemplate: ByteArray) {
                    val tmpBuffer = fpTemplate
                    val templateLen = fingerprintSensor!!.lastTempLen
                    //Base64 Template
                    //String strBase64 = Base64.encodeToString(tmpBuffer, 0, templateLen, Base64.NO_WRAP);
                    mActivity.runOnUiThread(Runnable {
                        if (isRegister) {
                            val bufids = ByteArray(ZKFingerService.getFPLimitCount())
                            var ret = ZKFingerService.identify(tmpBuffer, bufids, 55, 1)
                            if (ret > 0) {
                                val strRes = String(bufids).split("\t".toRegex())
                                    .dropLastWhile { it.isEmpty() }.toTypedArray()
                                onFingerListener.save(null, -99,"")
//                                textView.setText("the finger already enroll by " + strRes[0] + ",cancel enroll")
                                isRegister = false
                                enrollidx = 0
                                return@Runnable
                            }

                            if (enrollidx > 0 && ZKFingerService.verify(
                                    regtemparray[enrollidx - 1],
                                    tmpBuffer
                                ) <= 0
                            ) {
                                onFingerListener.save(null, -100,"")
//                                textView.setText("please press the same finger 3 times for the enrollment")
                                return@Runnable
                            }

                            System.arraycopy(tmpBuffer, 0, regtemparray[enrollidx], 0, 2048)
                            enrollidx++
                            if (enrollidx == 3) {
                                val regTemp = ByteArray(2048)
                                if (0 < (ZKFingerService.merge(
                                        regtemparray[0],
                                        regtemparray[1],
                                        regtemparray[2],
                                        regTemp
                                    ).also { ret = it })
                                ) {
//                                    ZKFingerService.save(regTemp, "test" + uid++)
                                    System.arraycopy(regTemp, 0, lastRegTemp, 0, ret)
                                    val strBase64 =
                                        Base64.encodeToString(regTemp, 0, ret, Base64.NO_WRAP)
                                    Base64.decode(strBase64, Base64.NO_WRAP)
                                    onFingerListener.save(regTemp, 0,strBase64)
                                } else {
                                    onFingerListener.save(regTemp, -1,"")
                                }
                                isRegister = false
                            } else {
                                onFingerListener.save(null, 3 - enrollidx,"")
                            }
                        } else {
                            val fPLimitCount = ZKFingerService.getFPLimitCount()
                            val bufids = ByteArray(fPLimitCount)
                            val ret = ZKFingerService.identify(tmpBuffer, bufids, 70, 1)
                            if (ret > 0) {
                                val strRes = String(bufids).split("\t".toRegex())
                                    .dropLastWhile { it.isEmpty() }.toTypedArray()
                                onFingerListener.verify(strRes, true)
                            } else {
                                onFingerListener.verify(null, false)
                            }
                        }
                    })
                }
            }
            fingerprintSensor?.setFingerprintCaptureListener(0, listener)
            fingerprintSensor?.startCapture(0)
            bstart = true
        } catch (e: FingerprintException) {
            onFingerListener.captureFail(e,"connectFail")
        }
        return fingerUtils!!
    }

    //停止指纹识别
    @Throws(FingerprintException::class)
    fun onBnStop() {
        try {
            fingerprintSensor?.stopCapture(0)
            bstart = false
            fingerprintSensor?.close(0)
            fingerprintSensor?.destroy()
        } catch (e: FingerprintException) {
Klog.d("----onBnStop--$e")
        }
        fingerUtils = null
    }

    //注册指纹
    fun onBnEnroll(): FingerUtils {
        if (bstart) {
            isRegister = true
            enrollidx = 0
//            textView.setText("You need to press the 3 time fingerprint")
        } else {
//            textView.setText("please begin capture first")
        }
        return fingerUtils!!
    }

    //验证指纹
    fun onBnVerify() {
        if (bstart) {
            isRegister = false
            enrollidx = 0
        } else {
//            textView.setText("please begin capture first")
        }
    }

    interface OnFingerListener {
        fun connectComplete()
        fun captureOK(bitmapFp: Bitmap)
        fun captureFail(err: FingerprintException, msg: String)
        fun extractError(err: Int)
        fun save(byteArray: ByteArray?, count: Int,strBase64:String)
        fun verify(byteArray: Array<String>?, isSuccess: Boolean)
    }
}